--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
vendor/lxmfy/README.md dev (af76f09d) Text, 10.57 KB
LXMFy
Feature
┌──────────────┬───────────────────────────────────────────────────────────────────────────────────┐
│ Category │ Key Capabilities │
├──────────────┼───────────────────────────────────────────────────────────────────────────────────┤
│ Core │ Interactive CLI, Command Prefixes, Cron-style Task Scheduler, Middleware & Event… │
│ Connectivity │ Direct Delivery & Propagation Fallback, Auto-Peering, RNS Link Support, Opportun… │
│ Security │ Spam Protection, Role-based Permissions, Identity Pinning, Message Signing/Verif… │
│ NLP │ Local NLP Intent Classification (Offline/Private), Type-hinted Argument Parsing │
│ Extensions │ Python Cogs, External Script Cogs (Bash, Go, C, etc.), Linux Sandboxing (Landloc… │
│ Storage │ Extensible Backends (JSON, SQLite, In-Memory), Message Persistence (Crash Recove… │
│ Reliability │ Extensive Stability & Mathematical Stress Testing, Chaos Engineering, Resource L… │
│ UX │ Help on First Message, Auto-generated Help Menus, Customizable Bot Icons, Attach… │
└──────────────┴───────────────────────────────────────────────────────────────────────────────────┘
Installation
There are many ways to install LXMFy, you pick:
From PyPI
T282828
T8b949e# pip
pip install lxmfy
T8b949e# pipx
pipx install lxmfy
Development Installation
For development, clone the repository and install with poetry:
T282828
git clone https://git.quad4.io/LXMFy/LXMFy.git
Tffa657cd LXMFy
T282828
poetry install
Usage
T282828
lxmfy
Create bots:
T282828
lxmfy create
Docker
Building Manually
To build the Docker image, navigate to the root of the project and run:
T282828
docker build -t lxmfy-test .
Once built, you can run the Docker image:
T282828
docker run -d Tffea00\
--name lxmfy-test-bot Tffea00\
-v Tff7b72$(Tffa657pwdTff7b72)/config:/bot/config Tffea00\
-v Tff7b72$(Tffa657pwdTff7b72)/.reticulum:/root/.reticulum Tffea00\
--restart unless-stopped Tffea00\
lxmfy-test
Auto-Interface support (network host):
T282828
docker run -d Tffea00\
--name lxmfy-test-bot Tffea00\
--network host Tffea00\
-v Tff7b72$(Tffa657pwdTff7b72)/config:/bot/config Tffea00\
-v Tff7b72$(Tffa657pwdTff7b72)/.reticulum:/root/.reticulum Tffea00\
--restart unless-stopped Tffea00\
lxmfy-test
Building Wheels with docker/Dockerfile.Build
The T383838docker/Dockerfile.Build is used to build the T383838lxmfy Python package into a wheel file within a Docker image.
T282828
docker build -f docker/Dockerfile.Build -t lxmfy-wheel-builder .
This will create an image named T383838lxmfy-wheel-builder. To extract the built wheel file from the image, you can run a container from this image and copy the T383838dist directory:
T282828
docker run --rm -v Ta5d6ff"Tff7b72$(Tffa657pwdTff7b72)Ta5d6ff/dist_output:/outputTa5d6ff" lxmfy-wheel-builder
This command will create a T383838dist_output directory in your current working directory and copy the built wheel file into it.
Example
T282828
Tff7b72from T7ee787lxmfy Tff7b72import Te6edf3LXMFBotTb4b4b4, Te6edf3load_cogs_from_directory
Te6edf3bot Tff7b72= Te6edf3LXMFBotTb4b4b4(
Te6edf3nameTff7b72=Ta5d6ff"Ta5d6ffLXMFy Test BotTa5d6ff"Tb4b4b4, T8b949e# Name of the bot that appears on the network.
Te6edf3announceTff7b72=T79c0ff5400Tb4b4b4, T8b949e# Announce every hour, set to 0 to disable.
Te6edf3announce_enabledTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Set to False to disable all announces (both initial and periodic)
Te6edf3announce_immediatelyTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Set to False to disable initial announce
Te6edf3adminsTff7b72=Tb4b4b4[Ta5d6ff"Ta5d6ffyour_lxmf_hash_hereTa5d6ff"Tb4b4b4]Tb4b4b4, T8b949e# List of admin hashes.
Te6edf3hot_reloadingTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Enable hot reloading.
Te6edf3command_prefixTff7b72=Ta5d6ff"Ta5d6ff/Ta5d6ff"Tb4b4b4, T8b949e# Set to None to process all messages as commands.
Te6edf3cogs_dirTff7b72=Ta5d6ff"Ta5d6ffcogsTa5d6ff"Tb4b4b4, T8b949e# Specify cogs directory name.
Te6edf3rate_limitTff7b72=T79c0ff5Tb4b4b4, T8b949e# 5 messages per minute
Te6edf3cooldownTff7b72=T79c0ff5Tb4b4b4, T8b949e# 5 seconds cooldown
Te6edf3max_warningsTff7b72=T79c0ff3Tb4b4b4, T8b949e# 3 warnings before ban
Te6edf3warning_timeoutTff7b72=T79c0ff300Tb4b4b4, T8b949e# Warnings reset after 5 minutes
Te6edf3signature_verification_enabledTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Enable cryptographic signature verification
Te6edf3require_message_signaturesTff7b72=Tff7b72FalseTb4b4b4, T8b949e# Allow unsigned messages but log them
Te6edf3propagation_fallback_enabledTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Enable propagation fallback after direct delivery fails
Te6edf3propagation_nodeTff7b72=Ta5d6ff"Ta5d6ffyour_propagation_node_hash_hereTa5d6ff"Tb4b4b4, T8b949e# Manual propagation node (optional)
Te6edf3autopeer_propagationTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Auto-discover propagation nodes (optional)
Te6edf3autopeer_maxdepthTff7b72=T79c0ff4Tb4b4b4, T8b949e# Max hops for auto-peering (default: 4)
Te6edf3enable_propagation_nodeTff7b72=Tff7b72FalseTb4b4b4, T8b949e# Run as propagation node (default: False)
Te6edf3message_storage_limit_mbTff7b72=T79c0ff500Tb4b4b4, T8b949e# Storage limit in MB for propagation node (default: 500)
Te6edf3direct_delivery_retriesTff7b72=T79c0ff3Tb4b4b4, T8b949e# Number of direct delivery attempts before falling back to propagation
Te6edf3landlock_enabledTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Linux Landlock LSM sandbox for the bot process (default)
Te6edf3external_cogs_sandbox_enabledTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Sandbox external script cogs on Linux
Te6edf3external_cogs_sandbox_typeTff7b72=Ta5d6ff"Ta5d6ffautoTa5d6ff"Tb4b4b4, T8b949e# auto, landlock, bwrap, firejail, or none
Tb4b4b4)
T8b949e# Dynamically load all cogs
Te6edf3load_cogs_from_directoryTb4b4b4(Te6edf3botTb4b4b4)
Tf0883e@botTff7b72.Td2a8ffcommandTb4b4b4(Te6edf3nameTff7b72=Ta5d6ff"Ta5d6ffpingTa5d6ff"Tb4b4b4, Te6edf3descriptionTff7b72=Ta5d6ff"Ta5d6ffTest if bot is responsiveTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8ffpingTb4b4b4(Te6edf3ctxTb4b4b4)Tb4b4b4:
Te6edf3ctxTff7b72.Td2a8ffreplyTb4b4b4(Ta5d6ff"Ta5d6ffPong!Ta5d6ff"Tb4b4b4)
T8b949e# Admin Only Command
Tf0883e@botTff7b72.Td2a8ffcommandTb4b4b4(Te6edf3nameTff7b72=Ta5d6ff"Ta5d6ffechoTa5d6ff"Tb4b4b4, Te6edf3descriptionTff7b72=Ta5d6ff"Ta5d6ffEcho a messageTa5d6ff"Tb4b4b4, Te6edf3admin_onlyTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72def Td2a8ffechoTb4b4b4(Te6edf3ctxTb4b4b4, Te6edf3messageTb4b4b4: Tffa657strTb4b4b4)Tb4b4b4:
Te6edf3ctxTff7b72.Td2a8ffreplyTb4b4b4(Te6edf3messageTb4b4b4)
Te6edf3botTff7b72.Td2a8ffrunTb4b4b4(Tb4b4b4)
RRC (Reticulum Relay Chat)
Bots can join RRC hubs as ordinary clients over RNS Links with CBOR envelopes:
T282828
Tff7b72from T7ee787lxmfy Tff7b72import Te6edf3LXMFBotTb4b4b4, Te6edf3RRCMessage
Te6edf3bot Tff7b72= Te6edf3LXMFBotTb4b4b4(
Te6edf3nameTff7b72=Ta5d6ff"Ta5d6ffRoomBotTa5d6ff"Tb4b4b4,
Te6edf3rrc_enabledTff7b72=Tff7b72TrueTb4b4b4,
Te6edf3rrc_hubsTff7b72=Tb4b4b4[Ta5d6ff"Ta5d6ffyour_rrc_hub_destination_hashTa5d6ff"Tb4b4b4]Tb4b4b4,
Te6edf3rrc_roomsTff7b72=Tb4b4b4[Ta5d6ff"Ta5d6fflobbyTa5d6ff"Tb4b4b4]Tb4b4b4,
Te6edf3rrc_nickTff7b72=Ta5d6ff"Ta5d6ffRoomBotTa5d6ff"Tb4b4b4,
Tb4b4b4)
Tf0883e@botTff7b72.Td2a8ffon_rrc
Tff7b72def Td2a8ffon_rrcTb4b4b4(Te6edf3eventTb4b4b4, Te6edf3clientTb4b4b4, Te6edf3payloadTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3event Tff7b72== Ta5d6ff"Ta5d6ffmsgTa5d6ff" Tff7b72and Tffa657isinstanceTb4b4b4(Te6edf3payloadTb4b4b4, Te6edf3RRCMessageTb4b4b4) Tff7b72and Te6edf3payloadTff7b72.Td2a8ffmentionTb4b4b4:
Te6edf3clientTff7b72.Td2a8ffsend_messageTb4b4b4(Te6edf3payloadTff7b72.Td2a8ffroomTb4b4b4, Ta5d6fffTa5d6ff"Ta5d6ffHeard you, Tffd700{Te6edf3payloadTff7b72.Td2a8ffnickTffd700}Ta5d6ff"Tb4b4b4)
Te6edf3botTff7b72.Td2a8ffrunTb4b4b4(Tb4b4b4)
Or connect at runtime with T383838bot.connect_rrc(hub_hash, rooms=["lobby"]).
Hub sessions persist across restarts by default (T383838rrc_persist_sessions=True). Outgoing LXMF messages are also persisted by default (T383838message_persistence_enabled=True) so a crash mid-queue does not drop them. The outbound queue is bounded (T383838message_queue_size, default 50) and drops the oldest message when full.
Propagation Node Configuration
LXMFy supports three modes for propagation node usage:
1. Manual Configuration
Set a specific propagation node by hash:
T282828
Te6edf3bot Tff7b72= Te6edf3LXMFBotTb4b4b4(
Te6edf3nameTff7b72=Ta5d6ff"Ta5d6ffMyBotTa5d6ff"Tb4b4b4,
Te6edf3propagation_fallback_enabledTff7b72=Tff7b72TrueTb4b4b4,
Te6edf3propagation_nodeTff7b72=Ta5d6ff"Ta5d6ffyour_propagation_node_hash_hereTa5d6ff"Tb4b4b4, T8b949e# Manual node configuration
Te6edf3direct_delivery_retriesTff7b72=T79c0ff3Tb4b4b4,
Tb4b4b4)
2. Automatic Discovery (Auto-Peering)
Let the bot automatically discover and use propagation nodes from network announces:
T282828
Te6edf3bot Tff7b72= Te6edf3LXMFBotTb4b4b4(
Te6edf3nameTff7b72=Ta5d6ff"Ta5d6ffMyBotTa5d6ff"Tb4b4b4,
Te6edf3propagation_fallback_enabledTff7b72=Tff7b72TrueTb4b4b4,
Te6edf3autopeer_propagationTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Enable automatic discovery
Te6edf3autopeer_maxdepthTff7b72=T79c0ff4Tb4b4b4, T8b949e# Maximum hop distance for auto-peering (default: 4)
Tb4b4b4)
The bot will listen for propagation node announces and automatically peer with suitable nodes within the configured hop depth.
3. Run as Propagation Node
Your bot can act as a propagation node itself to store and forward messages:
T282828
Te6edf3bot Tff7b72= Te6edf3LXMFBotTb4b4b4(
Te6edf3nameTff7b72=Ta5d6ff"Ta5d6ffMyPropagationBotTa5d6ff"Tb4b4b4,
Te6edf3enable_propagation_nodeTff7b72=Tff7b72TrueTb4b4b4, T8b949e# Enable propagation node mode
Te6edf3message_storage_limit_mbTff7b72=T79c0ff500Tb4b4b4, T8b949e# Limit storage to 500 MB (default)
Tb4b4b4)
When running as a propagation node, the bot will store messages for offline users and forward them when the recipients come online. The T383838message_storage_limit_mb prevents the bot from consuming unlimited disk space. Set to 0 for unlimited storage (not recommended).
Querying Propagation Status
You can check the current propagation configuration and discovered nodes:
T282828
Te6edf3status Tff7b72= Te6edf3botTff7b72.Td2a8ffget_propagation_node_statusTb4b4b4(Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffCurrent outbound node: Tffd700{Te6edf3statusTb4b4b4[Ta5d6ff'Ta5d6ffcurrent_outbound_nodeTa5d6ff'Tb4b4b4]Tffd700}Ta5d6ff"Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffDiscovered peers: Tffd700{Te6edf3statusTb4b4b4[Ta5d6ff'Ta5d6ffdiscovered_peersTa5d6ff'Tb4b4b4]Tffd700}Ta5d6ff"Tb4b4b4)
Dynamically Setting Propagation Node
You can change the propagation node at runtime:
T282828
Te6edf3botTff7b72.Td2a8ffset_propagation_nodeTb4b4b4(Ta5d6ff"Ta5d6ffnew_propagation_node_hashTa5d6ff"Tb4b4b4)
Managing Storage Limits
When running as a propagation node, you can query and adjust storage limits:
T282828
T8b949e# Get current storage statistics
Te6edf3stats Tff7b72= Te6edf3botTff7b72.Td2a8ffget_propagation_storage_statsTb4b4b4(Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffStorage used: Tffd700{Te6edf3statsTb4b4b4[Ta5d6ff'Ta5d6ffstorage_size_mbTa5d6ff'Tb4b4b4]Tffd700:Ta5d6ff.2fTffd700}Ta5d6ff MBTa5d6ff"Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffStorage limit: Tffd700{Te6edf3statsTb4b4b4[Ta5d6ff'Ta5d6ffstorage_limit_mbTa5d6ff'Tb4b4b4]Tffd700}Ta5d6ff MBTa5d6ff"Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffUtilization: Tffd700{Te6edf3statsTb4b4b4[Ta5d6ff'Ta5d6ffutilization_percentTa5d6ff'Tb4b4b4]Tffd700:Ta5d6ff.1fTffd700}Ta5d6ff%Ta5d6ff"Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffMessages stored: Tffd700{Te6edf3statsTb4b4b4[Ta5d6ff'Ta5d6ffmessage_countTa5d6ff'Tb4b4b4]Tffd700}Ta5d6ff"Tb4b4b4)
T8b949e# Change storage limit at runtime
Te6edf3botTff7b72.Td2a8ffset_message_storage_limitTb4b4b4(Te6edf3megabytesTff7b72=T79c0ff1000Tb4b4b4) T8b949e# Set to 1 GB
Important Notes
• Without configuring propagation (manual, auto-peer, or running as a node), messages requiring propagation will fail
• You can combine modes: e.g., set a manual node AND enable auto-peering as backup
• When running as a propagation node, your bot can still send and receive messages normally
• Auto-peering respects the T383838autopeer_maxdepth setting to avoid connecting to distant nodes
Security & Sandboxing
On Linux kernels with Landlock support (5.13+), LXMFy can restrict filesystem access for the bot process and for external script cogs.
Bot process sandbox
When T383838landlock_enabled=True (default), the bot applies a Landlock LSM sandbox after startup. System paths are read-only; bot storage, config, cogs, Reticulum config, and temp directories remain writable.
T282828
Te6edf3bot Tff7b72= Te6edf3LXMFBotTb4b4b4(
Te6edf3nameTff7b72=Ta5d6ff"Ta5d6ffSecureBotTa5d6ff"Tb4b4b4,
Te6edf3landlock_enabledTff7b72=Tff7b72TrueTb4b4b4,
Tb4b4b4)
Te6edf3status Tff7b72= Te6edf3botTff7b72.Td2a8ffget_landlock_statusTb4b4b4(Tb4b4b4)
Tffa657printTb4b4b4(Te6edf3statusTb4b4b4)
Environment overrides:
• T383838LXMFY_LANDLOCK=0 — disable Landlock
• T383838LXMFY_LANDLOCK=1 — force an attempt on Linux
• unset — follow T383838landlock_enabled and kernel auto-detection
External script cog sandbox
Executable cogs in T383838cogs/ can run in a restricted environment when T383838external_cogs_sandbox_enabled=True (default). Set T383838external_cogs_sandbox_type to:
• T383838auto (default) — prefer Landlock, then T383838bwrap, then T383838firejail
• T383838landlock — Landlock-only via T383838preexec_fn
• T383838bwrap — bubblewrap read-only bind sandbox
• T383838firejail — firejail private profile with no network
• T383838none — no subprocess sandbox
See the docs for full configuration details.
Development
• Python 3.11+
• Poetry
T282828
poetry install
poetry run lxmfy run Tffa657echo
Common Makefile targets:
T282828
make lint T8b949e# ruff check
make typecheck T8b949e# pyright lxmfy
make Tffa657test T8b949e# pytest
make ci T8b949e# lint, typecheck, security check, test, build
Contributing
For now send ideas and issues to LXMF: T3838387cc8d66b4f6a0e0e49d34af7f6077b5a
License
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────